using WebRtcProject.Hubs;
using WebRtcProject.Services;
using WebRtcProject.Services.Logging;
using WebRtcProject.Models.Configuration;
using Serilog;
using Serilog.Events;
using Serilog.Formatting.Compact;
using Microsoft.Extensions.Options;

var builder = WebApplication.CreateBuilder(args);

// 显式设置监听URL
builder.WebHost.UseUrls("http://0.0.0.0:5000", "https://0.0.0.0:5001");

// 配置 Serilog - 高性能异步批量写入
builder.Host.UseSerilog((context, services, configuration) =>
{
    var serilogOptions = context.Configuration.GetSection(SerilogOptions.SectionName).Get<SerilogOptions>() 
                        ?? new SerilogOptions();

    // 设置最小日志级别
    configuration.MinimumLevel.Is(Enum.Parse<LogEventLevel>(serilogOptions.MinimumLevel));

    // 添加上下文信息
    configuration
        .Enrich.FromLogContext()
        .Enrich.WithThreadId()
        .Enrich.WithProcessId()
        .Enrich.WithProcessName()
        .Enrich.WithEnvironmentName()
        .Enrich.WithMachineName();

    // 控制台输出 (异步)
    if (serilogOptions.EnableConsoleOutput)
    {
        if (serilogOptions.Async.Enabled)
        {
            configuration.WriteTo.Async(a => a.Console(
                outputTemplate: serilogOptions.File.OutputTemplate), 
                bufferSize: serilogOptions.Async.BufferSize,
                blockWhenFull: serilogOptions.Async.BlockWhenFull == 1);
        }
        else
        {
            configuration.WriteTo.Console(outputTemplate: serilogOptions.File.OutputTemplate);
        }
    }

    // 文件输出 (异步批量写入)
    if (serilogOptions.EnableFileOutput)
    {
        if (serilogOptions.Async.Enabled)
        {
            configuration.WriteTo.Async(a => a.File(
                path: serilogOptions.File.Path,
                rollingInterval: Enum.Parse<RollingInterval>(serilogOptions.File.RollingInterval),
                fileSizeLimitBytes: ParseFileSize(serilogOptions.File.FileSizeLimitBytes),
                retainedFileCountLimit: serilogOptions.File.RetainedFileCountLimit,
                buffered: serilogOptions.File.Buffered,
                flushToDiskInterval: TimeSpan.FromSeconds(serilogOptions.File.FlushToDiskInterval),
                rollOnFileSizeLimit: serilogOptions.File.RollOnFileSizeLimit,
                shared: serilogOptions.File.Shared,
                outputTemplate: serilogOptions.File.OutputTemplate),
                bufferSize: serilogOptions.Async.BufferSize,
                blockWhenFull: serilogOptions.Async.BlockWhenFull == 1);
        }
        else
        {
            configuration.WriteTo.File(
                path: serilogOptions.File.Path,
                rollingInterval: Enum.Parse<RollingInterval>(serilogOptions.File.RollingInterval),
                fileSizeLimitBytes: ParseFileSize(serilogOptions.File.FileSizeLimitBytes),
                retainedFileCountLimit: serilogOptions.File.RetainedFileCountLimit,
                buffered: serilogOptions.File.Buffered,
                flushToDiskInterval: TimeSpan.FromSeconds(serilogOptions.File.FlushToDiskInterval),
                rollOnFileSizeLimit: serilogOptions.File.RollOnFileSizeLimit,
                shared: serilogOptions.File.Shared,
                outputTemplate: serilogOptions.File.OutputTemplate);
        }
    }

    // 错误日志单独文件 (同步快速写入)
    configuration.WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => e.Level >= LogEventLevel.Error)
        .WriteTo.File(
            path: "logs/errors/error-.txt",
            rollingInterval: RollingInterval.Day,
            outputTemplate: serilogOptions.File.OutputTemplate));

    // 性能关键路径的快速日志
    foreach (var criticalNamespace in serilogOptions.Performance.CriticalNamespaces)
    {
        configuration.WriteTo.Logger(l => l
            .Filter.ByIncludingOnly(e => 
                e.Properties.ContainsKey("SourceContext") &&
                e.Properties["SourceContext"].ToString().Contains(criticalNamespace))
            .WriteTo.File(
                path: $"logs/critical/critical-{criticalNamespace.Replace(".", "-")}.txt",
                rollingInterval: RollingInterval.Hour,
                outputTemplate: "{Timestamp:HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}"));
    }

    // 结构化日志输出 (JSON格式)
    configuration.WriteTo.Logger(l => l
        .Filter.ByIncludingOnly(e => 
            serilogOptions.Performance.StructuredLoggingNamespaces.Any(ns =>
                e.Properties.ContainsKey("SourceContext") &&
                e.Properties["SourceContext"].ToString().Contains(ns)))
        .WriteTo.Async(a => a.File(
            new CompactJsonFormatter(),
            path: "logs/structured/structured-.json",
            rollingInterval: RollingInterval.Day),
            bufferSize: serilogOptions.Async.BufferSize));
});

// 解析文件大小字符串
static long? ParseFileSize(string fileSizeString)
{
    if (string.IsNullOrEmpty(fileSizeString)) return null;
    
    var size = fileSizeString.ToUpperInvariant();
    var multiplier = 1L;
    
    if (size.EndsWith("KB")) multiplier = 1024;
    else if (size.EndsWith("MB")) multiplier = 1024 * 1024;
    else if (size.EndsWith("GB")) multiplier = 1024 * 1024 * 1024;
    
    var numPart = size.Replace("KB", "").Replace("MB", "").Replace("GB", "");
    return long.TryParse(numPart, out var num) ? num * multiplier : null;
}

// 添加服务
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 全局配置 JSON 序列化为 camelCase
        options.JsonSerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase;
    });

// 配置 SignalR 使用 camelCase 序列化
builder.Services.AddSignalR()
    .AddJsonProtocol(options =>
    {
        // SignalR JSON 协议也使用 camelCase
        options.PayloadSerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase;
    });

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// 添加CORS支持
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.SetIsOriginAllowed(_ => true)  // 允许任何来源
              .AllowAnyMethod()
              .AllowAnyHeader()
              .AllowCredentials();  // SignalR 需要
    });
});

// 添加自定义服务
builder.Services.AddSingleton<IRoomService, RoomService>();
builder.Services.AddSingleton<IUserService, UserService>();

// 配置 RabbitMQ 外部服务连接
builder.Services.Configure<RabbitMQOptions>(
    builder.Configuration.GetSection(RabbitMQOptions.SectionName));
builder.Services.AddSingleton<RabbitMQService>();
builder.Services.AddSingleton<IRabbitMQService>(provider => provider.GetRequiredService<RabbitMQService>());

// 初始化 RabbitMQ 连接的后台服务
builder.Services.AddHostedService<RabbitMQInitializationService>();

// 配置 WebRTC 专用 RabbitMQ 服务
builder.Services.Configure<WebRtcRabbitMQOptions>(
    builder.Configuration.GetSection(WebRtcRabbitMQOptions.SectionName));
builder.Services.AddSingleton<WebRtcRabbitMQService>();
builder.Services.AddSingleton<IWebRtcRabbitMQService>(provider => provider.GetRequiredService<WebRtcRabbitMQService>());

// 初始化 WebRTC 专用 RabbitMQ 连接的后台服务
builder.Services.AddHostedService<WebRtcRabbitMQInitializationService>();

// 配置 Consul 服务发现和配置管理
builder.Services.Configure<ConsulOptions>(
    builder.Configuration.GetSection(ConsulOptions.SectionName));
builder.Services.AddSingleton<ConsulService>();

// 初始化 Consul 连接的后台服务
builder.Services.AddHostedService<ConsulInitializationService>();

// 配置 Serilog 高性能组件
builder.Services.Configure<SerilogOptions>(
    builder.Configuration.GetSection(SerilogOptions.SectionName));
builder.Services.AddSingleton<ILogResourceManager, LogResourceManager>();

// 添加内存和性能监控
builder.Services.AddHostedService<LogResourceManagerHostedService>();

// 注册高性能日志Sink (可选，用于特殊场景)
builder.Services.AddSingleton(provider =>
{
    var serilogOptions = provider.GetRequiredService<IOptions<SerilogOptions>>().Value;
    return new HighPerformanceLogSink(
        new Serilog.Formatting.Json.JsonFormatter(),
        serilogOptions.Performance,
        serilogOptions.ResourceControl.RateLimit,
        serilogOptions.Async.BufferSize);
});

var app = builder.Build();

// 配置HTTP请求管道
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseCors("AllowAll");
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

app.MapControllers();
app.MapHub<SignalingHub>("/signaling");

// 提供默认页面
app.MapGet("/", () => Results.Redirect("/index.html"));

app.Run(); 